import re
import json
import pickle
import difflib

from annoying.decorators import render_to
from django.http import HttpResponseRedirect

from django.template import loader
from django.template import Context
from django.template import Template
from django.template import TemplateDoesNotExist

from django.shortcuts import render_to_response

from core.models import Scan
from core.models import Result

from core.views.resources import New
from core.views.resources import Lists
from core.views.resources import Update

get_template = loader.get_template

class MakeDiff:
    def __init__(self):
        pass

    def set_items(self, *args, **kwargs):
        self.direct = kwargs['direct']
        self.proxy = kwargs['proxy']

    def diff(self, keys):
        self.diff_list = []
        tpl = get_template('diff_partial.html')
        diff_string = '<span class="%s">%s</span>'

        for key in keys:
            one = str(self.direct.get(key, '-')).strip()
            two = str(self.proxy.get(key, '-')).strip()

            if one not in two:
                one = diff_string % ('delete', one)
                two = diff_string % ('delete', two)
            else:
                one = diff_string % ('equal', one)
                two = diff_string % ('equal', two)

            self.diff_list.append({
                'header': key,
                'direct': one,
                'proxy': two
            })

        ctx = Context({ 'data': self.diff_list })

        return tpl.render(ctx)

def filters(request):
    pass

def get_header_list(results):
    all_headers = []

    for result in results:
        try:
            for item in result.header:
                keys = result.header[item].keys()

                for key in keys:
                    all_headers.append(key)
        except AttributeError:
            print result.header

    return list(set(all_headers))

def get_tpl(prefix, model):
    model_name = model.__name__.lower()
    template_name = '%s_%s.html' % (prefix, model_name)

    return model_name, template_name

@render_to('view_scan.html')
def view_scan(request, id):
    results = Result.objects.filter(scan = Scan.objects.filter(pk = int(id)))
    data = {}
    meta = []

    data.setdefault('messages', [])

    if len(results):
        headers = get_header_list(results = results)

        diffs = MakeDiff()

        for result in results:
            headers_direct = result.header.get('direct')
            headers_proxy = result.header.get('proxy')

            diffs.set_items(direct=headers_direct, proxy=headers_proxy)

            meta.append({
                'id': result.pk,
                'link': result.link_uri,
                'ip_links': result.ipaddrlist,
                'screenshot': result.screenshot,
                'dump': result.dump,
                'schedule': result.schedule,
                'headers': diffs.diff(headers)
            })

        data['messages'].append({
            'type': 'info',
            'body': 'Results'
        })

        data.setdefault('results', meta)

    return data

@render_to()
def display(request, model):
    model, template = get_tpl('list', model)
    func = Lists.map_action(model)
    path_info = request.META.get('PATH_INFO', None)

    data = func()

    if request.POST:
        add_func = New.map_action(path_info)
        messages = add_func(request)

        if messages['messages']:
            for item in messages['messages']:
                data['messages'].append(item)

    data.setdefault('TEMPLATE', template)

    return data

@render_to()
def view_item(request, id, model):
    model, template = get_tpl('view', model)
    path_info = request.META.get('PATH_INFO', None)

    if path_info:
        path = '/'.join(path_info.split('/')[:-1])

    if not id:
        HttpResponseRedirect('/%s' % model)

    func = Update.map_action(path)

    data = func(request = request, id = id)

    if dict is type(data):
        data.setdefault('TEMPLATE', template)

    return data

@render_to()
def change_status(request, id, model):
    model_name, template = get_tpl('view', model)
    path_info = request.META.get('PATH_INFO', None)
    path = '/'.join(path_info.split('/')[:-1])

    item = model.objects.get(pk = int(id))

    if 'enable' in path:
        item.use = True
    elif 'disable' in path:
        item.use = False

    item.save()

    return HttpResponseRedirect('/%s' % model_name)

@render_to()
def filters():
    pass
